/**
*	@file QueryVarTable.h
*
*	@brief this header defines query variable table
*
*	@author li yuchen
*
*	@date 1/28/2011
*/
#ifndef QUERYVARTABLE_H
#define QUERYVARTABLE_H

#include "TNode.h"
#include "GNode.h"
#include <string>
#include <sstream>
#include <vector>
using namespace std;

typedef int				QueryVarIdx;
typedef string			QueryVarName;
typedef TNodeType		QueryVarType;
typedef vector<bool>	QueryVarSet;

struct QueryVarEntry{
	/** @brief variable declared before the query, start from 1 */
	QueryVarIdx		qvar_idx;

	/** @brief variable name */
	QueryVarName	qvar_name;

	/** @brief the variable type */
	QueryVarType	qvar_type;
};


class QueryVarTable{
public:
	/** @return the number of VarEntries in VarTable */
	inline static int	GetSize(){ return vp_qvar_entries_.size();};

	/** 
	*	@brief if var_name already exist, print error and exit the program
	*		otherwise, add a new Variable and returns its QueryVarIdx
	*		pre-codition:
	*		only query processor part can call this procedure
	*		post-condition:
	*		p_var_page_root_ will be changed after the first time execution
	*		p_var_page_tail_ may be changed after each execution, condition stated above
	*		size_ may be changed after each execution, condition stated above
	*/
	static QueryVarIdx InsertQueryVar(QueryVarName qvar_name,TNodeType qvar_type);

	/**
	*	@return if var_name exists, returns its QuertVarIdx
	*		otherwise, return -1
	*/
	static QueryVarIdx GetQueryVarIdx(QueryVarName qvar_name);

	/**
	*	@brief pre-conditon: var_idx <= size_
	*	@return QueryVarName with var_idx
	*/
	static QueryVarName	GetQueryVarName(QueryVarIdx qvar_idx);

	/**
	*	@param qvar_idx must within the range of query variable table
	*	@return var type with var_idx;
	*/
	static TNodeType GetQueryVarType(QueryVarIdx qvar_idx);

	/** @return the string representation of the query variable table */
	static string	ToString();

	/** @brief clean up the query variable table */
	static void		ClearQueryVarTable();
	
private:
	static vector<QueryVarEntry*>	vp_qvar_entries_;

	static QueryVarEntry*			GetQueryVarEntry(QueryVarIdx qvar_idx);

	/**	
	*	@brief if var_name exists, assign *pp_var_entry to that referece and return true
	*		otherwise, return false
	*/
	static bool						CheckQueryVarNameExistence(QueryVarName qvar_name, QueryVarEntry** pp_qvar_entry);
};

#endif